package com.ajouroid.smartcoworker;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.StreamCorruptedException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;

import android.content.Context;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioRecord;
import android.media.AudioTrack;
import android.media.MediaRecorder;
import android.util.Log;

public class AudioSender {

	//public final static String server_ip = "172.30.1.16";
	final String TAG = "AudioSender";
	public AudioRecord recorder = null;
	private int bufferSize = 8192;
	public AudioTrack track;
	private Socket sock;
	private static final int RECORDER_SAMPLERATE = 8000;
	private static final int RECORDER_CHANNELS = AudioFormat.CHANNEL_CONFIGURATION_MONO;
	private static final int RECORDER_AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT;

	private static final int SAMPLE_INTERVAL = 200; // milliseconds
	// private static final int SAMPLE_SIZE = 2; // bytes per sample

	Context context;
	
	private boolean sender;

	public AudioSender(Context context, Socket socket) {
		this.context = context;
		this.sock = socket;
	}

	public void stopRecording() {
		sender = false;
		if (recorder != null)
		{
			recorder.stop();
			recorder.release();
			recorder = null;
		}
	}

	Thread recvThread; 
	
	public void recvAudio() {
		recvThread = new Thread(new Runnable() {
			public void run() {
				Log.e(TAG, "start recv thread, thread id: "
						+ Thread.currentThread().getId());
				track = new AudioTrack(AudioManager.STREAM_MUSIC,
						RECORDER_SAMPLERATE,
						RECORDER_CHANNELS,
						RECORDER_AUDIO_ENCODING, bufferSize,
						AudioTrack.MODE_STREAM);
				track.play();
				try {
					byte[] buf = new byte[bufferSize];
					
					ObjectInputStream ois = new ObjectInputStream(sock.getInputStream());
					//InputStream is = sock.getInputStream();
					
					sender=false;

					while (!sender) {
						//int size = is.read(buf);
						try {
							buf = (byte[])ois.readObject();
							if (buf != null)
							{
								//Log.d(TAG, "Audio rcvd: " + buf.length);
								track.write(buf, 0, buf.length);
								
								buf = null;
							}
						} catch (ClassNotFoundException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						} catch (IOException ie)
						{
							Log.d(TAG, "Exception on Receiving Audio");
							ie.printStackTrace();
							break;
						}
						
					}
						track.stop();
						track.release();

				} catch (SocketException se) {
					se.printStackTrace();
				} catch (IOException ie) {
					ie.printStackTrace();
				} catch (NegativeArraySizeException nase)
				{
					nase.printStackTrace();
				}
				
			} // end run
		});
		recvThread.start();
	}
	
	public void stopRecv()
	{
		sender=true;

		
	}


	public void sendAudio() {
		Thread thrd = new Thread(new Runnable() {
			public void run() {
				recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,
						RECORDER_SAMPLERATE, RECORDER_CHANNELS,
						RECORDER_AUDIO_ENCODING, bufferSize);

				recorder.startRecording();

				sender = true;
				
				Log.e(TAG, "Start to send audio, thread id: "
						+ Thread.currentThread().getId());
				int bytes_read = 0;
				int bytes_count = 0;

				byte[] buf = new byte[bufferSize];

				try {

					ObjectOutputStream bos = new ObjectOutputStream(sock.getOutputStream());
					//OutputStream os = sock.getOutputStream();
					while (sender) {
						try {
							bytes_read = recorder.read(buf, 0, bufferSize);
							
							byte[] stream = new byte[bytes_read];
							
							System.arraycopy(buf, 0, stream, 0, bytes_read);
							bos.writeObject(stream);
							bos.flush();
							//os.write(stream);
							//Log.d(TAG, "Audio sent: " + bytes_read);
							bytes_count += bytes_read;
							//Log.d(TAG, "bytes_count : " + bytes_count);
							Thread.sleep(SAMPLE_INTERVAL, 0);
						} catch (IOException ie) {
							Log.e(TAG, "Exception on Sending Audio");
						}
					}
				} catch (InterruptedException ie) {
					Log.e(TAG, "InterruptedException");
				} catch (FileNotFoundException fnfe) {
					Log.e(TAG, "FileNotFoundException");
				} catch (SocketException se) {
					Log.e(TAG, "SocketException");
				} catch (UnknownHostException uhe) {
					Log.e(TAG, "UnknownHostException");
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} 
			} // end run
		});
		thrd.start();
	}
}
